#include "util.h"

// --------------- 实现所需的额外头文件 ---------------
#include <cstdarg>       // 可变参数（DPrintf函数）
#include <chrono>        // 时间处理（system_clock）
#include <cstdio>        // 格式化输出（DPrintf/Format）
#include <iomanip>       // 时间格式化（setw等）
#include <sstream>       // 字符串流（Op序列化）
#include <stdexcept>     // 异常处理（Boost序列化）
#include <thread>        // 线程休眠（SleepMs）
#include <random>        // 随机数生成
#include <iostream>

namespace common {

// 调试日志打印实现
void DPrintf(const char* format, ...) {
    if (!DEBUG) {
        return;  // 调试模式关闭时不输出日志
    }

    // 获取当前时间并格式化
    auto now = std::chrono::system_clock::now();
    std::time_t now_time = std::chrono::system_clock::to_time_t(now);
    std::tm* local_time = std::localtime(&now_time);
    
    // 输出时间戳
    printf("[%04d-%02d-%02d %02d:%02d:%02d] ",
           local_time->tm_year + 1900,
           local_time->tm_mon + 1,
           local_time->tm_mday,
           local_time->tm_hour,
           local_time->tm_min,
           local_time->tm_sec);
    
    // 输出日志内容
    va_list args;
    va_start(args, format);
    vprintf(format, args);
    va_end(args);
    printf("\n");
}

// 断言工具实现
void Assert(bool condition, const std::string& message) {
    if (!condition) {
        std::cerr << "Error: " << message << std::endl;
        std::exit(EXIT_FAILURE);
    }
}

// 获取当前时间实现
std::chrono::system_clock::time_point Now() {
    return std::chrono::system_clock::now();
}

// 生成随机选举超时时间实现
std::chrono::milliseconds GetRandomizedElectionTimeout() {
    static std::random_device rd;  // 随机数种子
    static std::mt19937 rng(rd()); // 随机数生成器
    
    // 在指定范围内生成随机数
    std::uniform_int_distribution<int> dist(
        MIN_RANDOMIZED_ELECTION_TIME,
        MAX_RANDOMIZED_ELECTION_TIME
    );
    
    return std::chrono::milliseconds(dist(rng));
}

// 线程休眠实现
void SleepMs(int ms) {
    if (ms <= 0) {
        return;  // 无需休眠
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}

// Op类序列化实现
std::string Op::AsString() const {
    try {
        std::stringstream ss;
        boost::archive::text_oarchive oa(ss);
        oa << *this;  // 调用Boost序列化
        return ss.str();
    } catch (const std::exception& e) {
        DPrintf("Op serialization failed: %s", e.what());
        return "";
    }
}

bool Op::ParseFromString(const std::string& str) {
    try {
        std::stringstream ss(str);
        boost::archive::text_iarchive ia(ss);
        ia >> *this;
        return true;
    } catch (...) {
        return false;  // 反序列化失败
    }
}

std::ostream& operator<<(std::ostream& os, const Op& op) {
    os << "[MyClass:Operation{" << op.operation
       << "}, Key{" << op.key 
       << "}, Value{" << op.value 
       << "}, ClientId{" << op.client_id 
       << "}, RequestId{" << std::to_string(op.request_id) << "}]";  // 在这里实现自定义的输出格式
    return os;
}

// 端口检查实现
bool IsPortAvailable(unsigned short port) {
    // 创建TCP套接字
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
        DPrintf("Failed to create socket: %d", errno);
        return false;  // 套接字创建失败
    }
    DEFER [&]() {
        close(sock);
    };  // 确保套接字关闭

    // 设置地址结构
    sockaddr_in addr{};
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);  // 绑定本地地址

    // 尝试绑定端口（绑定成功说明端口可用）
    int ret = bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
    if (ret < 0) {
        DPrintf("Port %d is in use (errno: %d)", port, errno);
        return false;
    }
    return true;
}

// 获取可用端口实现
bool GetAvailablePort(short& port) {
    const short MAX_TRY = 30;  // 最大尝试次数
    short current_port = port;

    for (short i = 0; i < MAX_TRY; ++i) {
        if (IsPortAvailable(current_port)) {
            port = current_port;
            return true;
        }
        current_port++;
    }

    // 未找到可用端口
    port = -1;
    return false;
}

}  // namespace common